package com.restkeeper.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.restkeeper.dto.DyDevicesDto;
import com.restkeeper.dto.DyUserTimesDto;
import com.restkeeper.entity.*;
import com.restkeeper.mapper.*;
import com.restkeeper.service.DyDevicesService;
import com.restkeeper.utils.Result;
import com.restkeeper.utils.ResultCode;
import com.restkeeper.utils.Snowflake;
import com.restkeeper.utils.StringUtils;
import com.restkeeper.vo.DyDevicesVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class DyDevicesServiceImpl extends ServiceImpl<DyDevicesMapper, DyDevices> implements DyDevicesService {

    @Value("${douyin.startDeviceUrl}")
    private String startDeviceUrl;
    private final RedisTemplate redisTemplate;
    private final DyDevicesMapper dyDevicesMapper;
    private final DyUsersMapper usersMapper;
    private final DyUserTimesMapper timesMapper;
    private final DyTimesRecordMapper timesRecordMapper;
    private final DyMerchantMapper merchantMapper;
    private final SystemConfigMapper systemConfigMapper;


    @Override
    public Result startDevice(DyDevicesDto dto) {
        log.info("startDevice");
        if (StringUtils.isBlank(dto.getImei())){
            return Result.error("imei is null");
        }
        if (dto.getUserId()==null){
            return Result.error("请先登录");
        }
        //获取锁
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("startDevice:"+dto.getUserId()+":"+dto.getImei(),"1", 5, TimeUnit.SECONDS);
        if (!lock) {
            return Result.error(ResultCode.repeat_request,"请勿重复点击");
        }
        DyUsers dyUsers = usersMapper.selectById(dto.getUserId());
        if (dyUsers==null){
            return Result.error("用户不存在");
        }
        //根据imei查询设备
        DyDevicesVo devicesVo=dyDevicesMapper.selectByImei(dto.getImei());
        if (devicesVo==null){
            return Result.error("设备不存在");
        }
        if (devicesVo.getMerchantId()==null){
            return Result.error("设备未绑定");
        }

        DyUserTimesDto timesDto=new DyUserTimesDto();
        timesDto.setDeviceId(devicesVo.getId());
        timesDto.setMerchantId(devicesVo.getMerchantId());
        timesDto.setUserId(dto.getUserId());
        DyUserTimes times=timesMapper.selectUserTimes(timesDto);
        if(times==null){
            return Result.error("设备次数信息获取失败");
        }

        LambdaQueryWrapper<DyTimesRecord> recordW=new LambdaQueryWrapper<>();
        recordW.eq(DyTimesRecord::getUserId,dto.getUserId());
        recordW.eq(DyTimesRecord::getDeviceId,devicesVo.getId());
        recordW.eq(DyTimesRecord::getMerchantId,devicesVo.getMerchantId());
        int usedCount = timesRecordMapper.selectCount(recordW);
        if(usedCount>=times.getTimes()){
            return Result.error("次数已用完");
        }
        //新增一条DyUserTimes数据
        Snowflake snowflake=new Snowflake(1,1);
        DyTimesRecord in=new DyTimesRecord();
        in.setId(snowflake.nextId());
        in.setDeviceId(devicesVo.getId());
        in.setMerchantId(devicesVo.getMerchantId());
        in.setUserId(Long.parseLong(dto.getUserId()));
        in.setCreateTime(new Date());
        timesRecordMapper.insert(in);
        return Result.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deviceInfo(DyDevicesDto dto) {
        JSONObject res=new JSONObject();
        res.put("usedCount",0);
        res.put("totalCount",0);
        if (StringUtils.isBlank(dto.getImei())){
            return Result.ok(res);
        }
        if (dto.getUserId()==null){
            return Result.error("请先登录");
        }
        DyUsers dyUsers = usersMapper.selectById(dto.getUserId());
        if (dyUsers==null){
            return Result.error("用户不存在");
        }
        //根据imei查询设备
        DyDevicesVo devicesVo=dyDevicesMapper.selectByImei(dto.getImei());
        if (devicesVo==null){
            return Result.error("设备不存在");
        }
        if (devicesVo.getMerchantId()==null){
            return Result.error("设备未绑定");
        }

        DyMerchant merchant = merchantMapper.selectById(devicesVo.getMerchantId());
        if (merchant==null){
            return Result.error("设备用户不存在");
        }
        DyUserTimesDto timesDto=new DyUserTimesDto();
        timesDto.setDeviceId(devicesVo.getId());
        timesDto.setMerchantId(devicesVo.getMerchantId());
        timesDto.setUserId(dto.getUserId());
        DyUserTimes times=timesMapper.selectUserTimes(timesDto);
        int totalCount=0;
        int usedCount=0;
        if(times==null){
            SystemConfig systemConfig = systemConfigMapper.selectOneByKey("initCount");
            if(systemConfig!=null && StringUtils.isNotBlank(systemConfig.getSysValue())){
                totalCount=Integer.parseInt(systemConfig.getSysValue());
            }
            Snowflake snowflake=new Snowflake(1,1);
            //新增一条DyUserTimes数据
            DyUserTimes in=new DyUserTimes();
            in.setId(snowflake.nextId());
            in.setDeviceId(devicesVo.getId());
            in.setMerchantId(devicesVo.getMerchantId());
            in.setUserId(Long.parseLong(dto.getUserId()));
            in.setCreateTime(new Date());
            in.setTimes(totalCount);
            timesMapper.insert(in);
        }else {
            totalCount=times.getTimes();
        }
        LambdaQueryWrapper<DyTimesRecord> recordW=new LambdaQueryWrapper<>();
        recordW.eq(DyTimesRecord::getUserId,dto.getUserId());
        recordW.eq(DyTimesRecord::getDeviceId,devicesVo.getId());
        recordW.eq(DyTimesRecord::getMerchantId,devicesVo.getMerchantId());
        usedCount = timesRecordMapper.selectCount(recordW);
        res.put("usedCount",usedCount>totalCount?totalCount:usedCount);
        res.put("totalCount",totalCount);
        res.put("merchant",merchant);
        return Result.ok(res);
    }
}